﻿/**

 @Name：swui.helper 桌面助手模块
 @Author：Zxq
 @License：MIT
    
 */

layui.define(['jquery', 'swui'], function (exports) {
    "use strict";

    var $ = layui.jquery,hideTimer;

    //助手构造函数
    var Helper = function () {
        swui.baseObject.call(this, 'helper');
        this.helps = {};
        this.Mode = 'normal';
        this.image = 'images/p1.png';//默认助手图片
    };

    //默认配置
    Helper.prototype = {
        //初始化html元素及事件
        render: function (callback) {
            if (this.configs.close === true) {
                this.configs.close = false;
            }
            else {
                var othis = this;
                if (!othis.configs.container) return;
                othis.elem = $('<div class="swui-helper layui-hide"></div>').appendTo(swui.elems.body);
                othis.msgbox = $('<div class="swui-bubble top"></div>').appendTo(othis.elem);
                othis.helpBtn = $('<li class="swui-taskbar-helper"></li>').appendTo(swui.elems.taskIcons.find('ul'));//任务栏的小助手
                layui.link(swui.path + 'css/helper.css', 'helper');
                setTimeout(function(){othis.elem.removeClass(othis.cssName.HIDE);},100);
                if (othis.configs.anima) othis.elem.addClass('on');

                othis.setData({urlcode:'uihelper'}, function (data) {
                    othis.data = data;
                    othis.renderElems();
                }, false);
            }
            //调用渲染完毕的回调函数
            if (this.Utils.isFunction(callback))
                callback.call(this);
        }
        ,renderElems: function () {
            //if (this.data === null) return;
            var helperSrc = this.data.image;
            if (!helperSrc) helperSrc = this.image;
            this.elem.css('background-image','url('+ helperSrc+')');
            this.helpBtn.css('background-image','url('+ helperSrc+')');
            if (this.data.msg)
                this.msgbox.html(this.data.msg);
            else this.hideMessage();
            var othis = this;
            if (this.data.menus) {
                this.menu = $('<ul class="swui-helper-menu"></ul>').appendTo(this.elem);
                var btnmenu = $('<ul class="helper-contextmenu"></ul>').appendTo(othis.helpBtn);
                $(this.data.menus).each(function (index, item) {
                    var cm = othis.configs.events[item];
                    if (cm) {
                        othis.menu.append('<li data-code="'+item+'" title="'+cm.name+'">'+othis.getIconHtml(cm.icon)+'</li>');
                        btnmenu.append('<li data-code="'+item+'" title="'+cm.name+'">'+othis.getIconHtml(cm.icon)+'</li>');
                    }
                });
            }
            
            othis.resetEvents();
        }
        ,resetEvents: function () {
            var othis = this;
            this.kid = drag.init(othis.elem[0],{container:othis.configs.container,selfonly:true,afterMove:function(){othis.locaMsgBox()}});
            othis.resetEvent('click', this.elem, function(e){
                if (othis.Mode === 'guide' || othis.Mode === 'menu') return;
                else if (othis.Mode === 'run') {//瞎跑模式
                    var p = {},o = $(othis.configs.container).offset();
                    var l = $(othis.configs.container).outerWidth()-othis.elem.outerWidth();
                    var t = $(othis.configs.container).outerHeight()-othis.elem.outerHeight();
                    p.left = o.left+Math.floor(Math.random() * l);
                    p.top = o.top+Math.floor(Math.random() * t);
                    othis.moveTo(p, function(){othis.showAutoMessage('点我就瞎跑');});
                }
                else {
                    var d = othis.data.msgs;
                    var msg = d[Math.floor(Math.random() * d.length)];
                    othis.showAutoMessage(msg);
                }
            }, null, true);
            othis.resetEvent('dblclick', this.elem, function(e){
                if (othis.Mode === 'guide' || othis.Mode === 'menu') return;
                othis.showAutoMessage('双击开启瞎跑模式');
                othis.setMode('run');
                othis.kid.setMoveAble(false);
            },null, true);
            othis.resetEvent('contextmenu', this.elem, function(e){
                if (othis.Mode === 'guide') return;
                othis.showAutoMessage('这是右键菜单');
                if (othis.menu.css('display') === 'none') {
                    othis.setMode('menu');
                    othis.menu.show();
                    var setTime = function (index){
                        setTimeout(function(){
                            othis.menu.children('li:eq('+index+')').show();
                            if (++index<othis.menu.children('li').length) {
                                setTime(index);
                            }
                        },100);
                    }
                    setTime(0);
                }
                else {
                    othis.setMode('normal');
                    othis.menu.hide();
                    othis.menu.children('li').css({display:''});
                }
            },null, true);
            //小助手右键功能项
            othis.resetEvent('click mousedown','li', function(e){
                var item = othis.configs.events[$(this).data('code')];
                if (item && othis.Utils.isFunction(item.handler)) {
                    item.handler.call(this);
                }
                othis.sp(e);
            },othis.menu);
            //绑定右下角小助手点击事件
            othis.resetEvent('click', othis.helpBtn, function(){
                if (othis.configs.anima)
                    othis.elem.toggleClass('on').toggleClass('off');
                else othis.elem.toggleClass(othis.cssName.HIDE);
            });
            //绑定右下角小助手右键事件
            othis.resetEvent('click mousedown','.helper-contextmenu li', function(e){
                var item = othis.configs.events[$(this).data('code')];
                if (item && othis.Utils.isFunction(item.handler)) {
                    item.handler.call(this);
                }
                othis.sp(e);
            },othis.helpBtn);
            othis.resetEvent('mouseenter', this.msgbox, function(e){
                clearTimeout(hideTimer);
            });
            othis.resetEvent('mouseleave', this.msgbox, function(e){
                if (othis.Mode === 'guide') return;
                hideTimer = setTimeout(function (){
                    othis.msgbox.hide();
                }, 3000);
            });
            //消息框内的按钮事件
            othis.resetEvent('click', '.swui-guide-operate a', function(e){
                if (!othis.msgbox.buttons) return;
                var btn = othis.msgbox.buttons[$(this).index()];
                if (!btn || !othis.Utils.isFunction(btn.handler)) return;
                if (btn.hide) othis.hideMessage();
                btn.handler.call(this, e);
            },othis.msgbox);
        }
        //自适应大小事件
        ,resizeEvent: function (e) {
            this.locaHelper();
            if (this.Mode === 'guide') {
                var othis = this;
                this.guideToElem(function(){othis.locaMsgBox(true);});
            }
        }
        //改变模式：normal/guide/run/menu
        ,setMode: function (mode) {
            if (this.Mode === mode) return;
            switch (mode) {
                case 'guide':
                case 'run':
                    this.kid.setMoveAble(false);
                    if (this.Mode === 'menu') {
                        this.menu.hide();
                        this.menu.children('li').css({display:''});
                    }
                    break;
                default:
                    this.kid.setMoveAble(true);
                    break;
            }
            this.Mode = mode;
        }
        //小助手移动函数(动画)
        ,moveTo: function (pos, callback) {
            var othis = this;
            this.elem.animate(pos, {
                duration: 500,
                complete: function(){
                    if (othis.Utils.isFunction(callback))
                        callback.call(this);
                }
                //progress: function(animation, progress) {
                    //console.log(Math.round(progress * 100));
                //   if (progress === 1) callback.call(this);
                //}
            });
        }
        //显示小助手
        ,show: function () {
            if (othis.configs.anima)
                this.elem.removeClass('off').addClass('on');
            else this.elem.removeClass(this.cssName.HIDE);
        }
        //隐藏小助手
        ,hide: function () {
            if (othis.configs.anima)
                this.elem.removeClass('on').addClass('off');
            else this.elem.addClass(this.cssName.HIDE);
        }
        ,open: function (callback) {
            if ($('.swui-helper').length > 0) return;
            this.render(callback);
        }
        //关闭小助手
        ,close: function () {
            this.elem.remove();
            this.setMode('normal');
            this.helpBtn.remove();
        }
        //定位小助手
        ,locaHelper: function () {
            var parentElem = $(this.configs.container);
            var bubble = this.elem;
            if (!bubble || bubble.length === 0) return;
            var ppos = parentElem.offset();
            var bpos = bubble.offset();
            var pos = {};
            if (bubble.outerWidth()+bpos.left > parentElem.outerWidth()+ppos.left)
                pos.left = parentElem.outerWidth()+ppos.left-bubble.outerWidth();
            else if (bpos.left < ppos.left)
                pos.left = ppos.left;
            if (bubble.outerHeight()+bpos.top > parentElem.outerHeight()+ppos.top)
                pos.top = parentElem.outerHeight()+ppos.top-bubble.outerHeight();
            else if (bpos.top < ppos.top)
                pos.top = ppos.top;
            this.elem.css(pos);
        }
        //定位消息框
        ,locaMsgBox:function(onTop){
            var parentElem = $(this.configs.container);
            var bubble = this.msgbox;
            var ppos = parentElem.offset();
            var bpos = bubble.offset();
            if (onTop) {
                if (!bubble.hasClass('top'))
                    bubble.removeClass('right left').addClass('top');
                bpos = bubble.offset();
                if (bpos.top < 0)
                    this.elem.css({top:this.elem.offset().top-bpos.top});
            }
            else if (bpos.top < 0 && bubble.hasClass('top')) {
                /*if (bubble.outerWidth()+bpos.left+this.elem.outerWidth()+10 > parentElem.outerWidth()+ppos.left)
                    bubble.removeClass('right left top').addClass('left');
                else bubble.removeClass('right left top').addClass('right');*/
                bubble.removeClass('top').addClass('right');
                bpos = bubble.offset();
                if (bubble.outerWidth()+bpos.left > parentElem.outerWidth()+ppos.left)
                    bubble.removeClass('right').addClass('left');
            }
            else if (!bubble.hasClass('top')) {
                if (bpos.top-bubble.outerHeight()-10>ppos.top)
                    bubble.removeClass('right left').addClass('top');
                /*else if (bubble.hasClass('right') && bubble.outerWidth()+bpos.left > parentElem.outerWidth()+ppos.left)
                    bubble.removeClass('right').addClass('left');
                else if (bubble.hasClass('left') && bubble.outerWidth()*2+bpos.left+this.elem.outerWidth()-40 < parentElem.outerWidth()+ppos.left) 
                    bubble.removeClass('left').addClass('right');*/
                else {
                    if (!bubble.hasClass('right'))
                        bubble.removeClass('left').addClass('right');
                    bpos = bubble.offset();
                    if (bubble.outerWidth()+bpos.left > parentElem.outerWidth()+ppos.left)
                        bubble.removeClass('right').addClass('left');
                }
            }
        }
        //显示消息 
        ,showMessage: function (option) {
            if (!this.elem || this.elem.css("display") == 'none')
                return;
            var message, timeout, onTop;
            if (this.Utils.isString(option)) {
                message = option;
                timeout = 0;
                onTop = false;
            }
            else {
                message = option.message;
                timeout = option.timeout || 0;
                onTop = option.onTop || false;
            }
            if (!message) return;
            clearTimeout(hideTimer);
            this.msgbox.buttons = option.buttons;
            if (option.buttons && option.buttons.length > 0) {
                message += '<div class="swui-guide-operate">';
                $.each(option.buttons, function(index, btn){
                    message += '<a href="javascript:void(0);">'+btn.name+'</a>';
                });
                message += '</div>';
            }
            this.msgbox.html(message).show();
            this.locaMsgBox(onTop);
            if (timeout > 0) {
                var othis = this;
                hideTimer = setTimeout(function (){
                    othis.msgbox.hide();
                }, timeout);
            }
        }
        //隐藏消息 
        ,hideMessage: function () {
            this.msgbox && this.msgbox.hide();
        }
        //显示消息自动隐藏 
        ,showAutoMessage: function (option) {
            var timeout;
            if (this.Utils.isString(option)){
                option = {message:option,timeout:5000};
            }
            else if (this.Utils.isObject(option)) {
                !option.timeout && (option.timeout = 5000);
            }
            else return;
            this.showMessage(option);
        }
        //向导指引模式
        ,guideMode: function (objs) {
            this.setMode('guide');
            var othis = this;
            //var shade = $('<canvas id="canvasId" class="swui-guide"></canvas>').appendTo('body');
            var shade = $('<div class="swui-guide"><div class="swui-guide-top"></div><div class="swui-guide-left"></div><div class="swui-guide-body"></div><div class="swui-guide-right"></div><div class="swui-guide-bottom"></div></div>').appendTo('body');

            var i = -1;
            this.resetEvent('click', shade, function(e){
                e=e||window.event;
                if ($(e.target||e.srcElement).is('.swui-guide-body')&&objs[i].event) return false;
                i++;
                //结束向导模式
                if (i === objs.length) {
                    guideEnd();
                    return;
                }
                var ind = i;//移动小助手的动画有延迟，为避免延迟后i值已变成objs.length而导致后面报错，因此用ind替换i
                othis.guideElem = $(objs[ind].elem);
                var msg = objs[ind].tip;
                var btns = [];
                if (objs[ind].exit) {
                    btns.push({name:'退出向导',handler:function(e){ guideEnd(); othis.sp(e); }});
                }
                if (objs[ind].prev) {
                    btns.push({name:'上一步',handler:function(e){ i -= 2; shade.trigger('click'); }});
                }
                othis.guideToElem(function(){
                    if (objs[ind].event) {
                        othis.resetEvent(objs[ind].event, '.swui-guide-body', function(){
                            $(this).off(objs[ind].event);
                            othis.guideElem.trigger(objs[ind].event);
                        },shade);
                    }
                    othis.showMessage({message:msg,onTop:true,buttons:btns});
                });
                othis.sp(e);
            });
            var guideEnd = function(){
                othis.setMode('normal');
                shade.remove();
                othis.hideMessage();
            }
            shade.trigger('click');
        }
        //指引到某个元素旁边
        ,guideToElem: function ($item,callback) {
            if (this.Utils.isFunction($item) && !callback){
                callback = $item;
                $item = null;
            }
            !$item && ($item = this.guideElem);
            if ($item.length === 0 || $item.is(':hidden')) return;
            var p = $item.offset();
            var shade = $('.swui-guide');
            p.width = $item.outerWidth();
            p.height = $item.outerHeight();
            if (shade.length > 0) {//向导模式锁屏点击指引元素
                shade.children('.swui-guide-top').css({height:p.top});
                shade.children('.swui-guide-bottom').css({top:p.top+p.height});
                shade.children('.swui-guide-left').css({marginTop:p.top,height:p.height,width:p.left});
                shade.children('.swui-guide-right').css({marginTop:p.top,left:p.left+p.width,height:p.height});
                shade.children('.swui-guide-body').css(p);
                //var canvas = document.getElementById("canvasId");
                //var context = canvas.getContext("2d");
                //context.clearRect(p.left,p.top,p.width,p.height);//抠出一个矩形区域
            }
            var t = p.top - (this.elem.outerHeight()-p.height) / 2;
            var l = p.left+p.width;
            if (l+this.elem.outerWidth()>$(document).width()) {
                l = p.left-this.elem.outerWidth();
                if (l < 0) {//放至目标元素中间区域
                    l = p.left + (p.width - this.elem.outerWidth()) / 2;
                }
            }
            if (t+this.elem.outerHeight()>$(document).height()) {
                t = p.top-this.elem.outerHeight();
                if (t < 0) {//放至目标元素中间区域
                    t = p.top + (p.height - this.elem.outerHeight()) / 2;
                }
                else {//放到正上方
                    l = p.left - (this.elem.outerWidth()-p.width) / 2;
                    if (l+this.elem.outerWidth()>$(document).width())
                        l = $(document).width()-this.elem.outerWidth();
                    else if (l<0)
                        l = 0;
                }
            }
            //定位小助手
            this.moveTo({left:l,top:t},callback);
        }
    };

    var helper = new Helper();

    swui.helper = helper;

    exports(helper.MOD_NAME, {});

    delete layui.helper;
});